﻿namespace MetaVideoEditorEvolved.Helper
{
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Drawing;
	using System.IO;
	using System.Net;
	using System.Text;
	using System.Web;
	using System.Xml.Linq;
	using ICSharpCode.SharpZipLib.Zip;

	using System;

	public class DownloadManager
	{
		public static WebResponse RetrieveFile(string url)
		{
			HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
			request.UserAgent = "MetaVideoEditorEvolved";
			request.Timeout = 20000;
			request.Proxy = WebRequest.DefaultWebProxy;
			request.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
			
			WebResponse resp = request.GetResponse();
			
			return resp;
		}
		
		public static Image RetrieveImage(string url)
		{
			Tracer.TracerInstance.TraceInformation(
				string.Format("Start download the url : {0}",
				              url));
			DateTime beginTime = DateTime.Now;
			
			WebResponse resp = null;
			
			try
			{
				try
				{
					resp = RetrieveFile(url);
				}
				catch
				{
					resp = RetrieveFile(url);
				}

				if(resp != null)
				{
					Tracer.TracerInstance.TraceInformation(
						string.Format("End download the url : {0} - Time elapsed : {1}",
						              url,
						              DateTime.Now.Subtract(beginTime)));
					
					return Image.FromStream(resp.GetResponseStream());
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(ex);
			}
			finally
			{
				resp.Close();
			}
			
			return null;
		}
		
		public static XDocument RetrieveXmlWebRequest(string url)
		{
			Tracer.TracerInstance.TraceInformation(string.Format("Start download the url : {0}", url));
			WebResponse resp = null;
			
			try
			{
				DateTime beginTime = DateTime.Now;
				
				try
				{
					resp = RetrieveFile(url);
				}
				catch
				{
					resp = RetrieveFile(url);
				}
				
				using (Stream s = resp.GetResponseStream())
				{
					var doc = XDocument.Parse(new StreamReader(s).ReadToEnd());
					s.Close();
					
					Tracer.TracerInstance.TraceInformation(string.Format("End download the url : {0} - Time elapsed : {1}", url, DateTime.Now.Subtract(beginTime)));
					
					return doc;
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(ex);
				return null;
			}
			finally
			{
				resp.Close();
			}
		}
		
		public static  List<KeyValuePair<string, XDocument>> UnzipXmlDocument(string url, string providerId)
		{
			try
			{
				List<KeyValuePair<string, XDocument>> xdocuments = new List<KeyValuePair<string, XDocument>>();
				
				string pathDirectory = Path.Combine(Path.GetTempPath(), providerId);
				
				if(Directory.Exists(pathDirectory))
				{
					if(Directory.GetCreationTime(pathDirectory) > DateTime.Now.AddDays(1))
					{
						Directory.Delete(pathDirectory, true);
					}
					else
					{
						foreach (var element in new DirectoryInfo(pathDirectory).GetFiles()) {
							xdocuments.Add(new KeyValuePair<string, XDocument>(element.Name, XDocument.Parse(new StreamReader(element.FullName).ReadToEnd())));
						}
						
						Tracer.TracerInstance.TraceSuccessOperation(string.Format("This file ({0}) is already downloaded today", url));
						
						return xdocuments;
					}
				}

				Directory.CreateDirectory(pathDirectory);
				
				Tracer.TracerInstance.TraceInformation(
					string.Format("Start download the url : {0}",
					              url));
				DateTime beginTime = DateTime.Now;
				
				WebResponse resp = null;
				
				try
				{
					resp = RetrieveFile(url);
				}
				catch
				{
					resp = RetrieveFile(url);
				}
				
				if(resp != null)
				{
					ZipInputStream zipInStream = new ZipInputStream(resp.GetResponseStream());
					ZipEntry entry = zipInStream.GetNextEntry();
					
					while (entry != null)
					{
						using(FileStream fileStreamOut = new FileStream(Path.Combine(pathDirectory, entry.Name), FileMode.Create, FileAccess.Write))
						{
							int size;
							byte[] buffer = new byte[4096];
							
							do
							{
								size = zipInStream.Read(buffer, 0, buffer.Length);
								fileStreamOut.Write(buffer, 0, size);
							} while (size > 0);
						}
						
						xdocuments.Add(new KeyValuePair<string, XDocument>(entry.Name, XDocument.Parse(new StreamReader(Path.Combine(pathDirectory, entry.Name)).ReadToEnd())));
						
						entry = zipInStream.GetNextEntry();
					}
					
					zipInStream.Close();
				}
				
				Tracer.TracerInstance.TraceInformation(
					string.Format("End download the url : {0} - Time elapsed : {1}",
					              url,
					              DateTime.Now.Subtract(beginTime)));
				
				return xdocuments;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError("Exception in the unzipXmlDocument for " + url, ex);
				return null;
			}
		}
		
		public static void RetrieveTrailer(string url, string destination)
		{
			Tracer.TracerInstance.TraceInformation(
				string.Format("Start download the url : {0}",
				              url));
			DateTime beginTime = DateTime.Now;
			
			WebResponse resp = null;
			
			try
			{
				try
				{
					resp = RetrieveFile(url);
				}
				catch
				{
					resp = RetrieveFile(url);
				}

				if(resp != null)
				{
					Stream stream = resp.GetResponseStream();
					
					FileStream fileStreamOut = new FileStream(destination, FileMode.CreateNew);
					
					int size;
					byte[] buffer = new byte[4096];
					
					do
					{
						size = stream.Read(buffer, 0, buffer.Length);
						fileStreamOut.Write(buffer, 0, size);
					} while (size > 0);
					
					fileStreamOut.Close();
					
					Tracer.TracerInstance.TraceInformation(
						string.Format("End download the url : {0} - Time elapsed : {1}",
						              url,
						              DateTime.Now.Subtract(beginTime)));
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(ex);
			}
			finally
			{
				resp.Close();
			}
		}

		public static string UrlEncode(string url)
		{
			return HttpUtility.UrlEncode(url);
		}
	}
}